package chat.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import chat.server.statemachine.election.AlgorithmElection;
import chat.server.statemachine.election.ElectionTokenContent;
import chat.server.statemachine.mutex.AlgorithmMutex;
import chat.server.statemachine.mutex.MutexAskContent;
import chat.server.statemachine.mutex.MutexTokenContent;

/**
 * Thread started by server to listen for commands
 * Type '?' in thrad to get list of commands
 * 
 * 	- election: start process of election"
 *	- askmutex: ask for a new mutex
 *  - tokenmutex: create the first token mutex"
 *  - hasmutex: tellf if this server has the mutex token
 *  - identity: list of neighbors identities
 *  
 * @author Baptiste Lafontaine
 * @author Arsène Huot
 * 
 */
public class ChatServerInput implements Runnable {
	BufferedReader bufin;
	ChatServerState sstate;

	public ChatServerInput (final ChatServerState sstate) {
		this.sstate = sstate;
	}

	public void run() {
		bufin = new BufferedReader(new InputStreamReader(System.in));
		while (true) {
			String s;
			try {
				s = bufin.readLine();
				if (s == null) {
					break;
				}
				/* Start election */
				if (s.equals("election")) {
					System.out.println("Starting election !");
					sstate.caw = sstate.identity;
					/* caw := p */
					System.out.println("Send initator tokens from : " + sstate.identity);
					ElectionTokenContent etc = new ElectionTokenContent(sstate.identity,sstate.identity);
					sstate.server.sendToAllServers(AlgorithmElection.TOKEN_MESSAGE.getActionIndex(), etc);
				}
				/* Start asking mutex */
				else if (s.equals("askmutex")) {
					if (!sstate.hasToken) {
						sstate.ns++;
						sstate.waitingForMutexToken = true;

						MutexAskContent mac = new MutexAskContent(sstate.identity,sstate.ns);
						sstate.server.sendToAllServers(AlgorithmMutex.TOKEN_MUTEX_ASK.getActionIndex(), mac);
					}
					else {
						System.out.println(sstate.identity + " you already have the mutex token !");
					}
				}
				/* Create the first mutex content */
				else if (s.equals("tokenmutex")) {
					System.out.println("Creating a new token");
					/* No ask, create a new token */
					MutexTokenContent mtc = new MutexTokenContent(sstate.identity,sstate.ns);
					sstate.mutexTokenContent = mtc;
					sstate.hasToken = true;
					sstate.ns++;
					System.out.println(sstate.identity + " has mutex token !");
				}
				else if (s.equals("hasmutex")) {
					if (sstate.hasToken) { System.out.println("I have mutex token"); }
					else { System.out.println("I don't have token"); }
				}
				/* List of neighbors' identity */
				else if (s.equals("identity")) {
					System.out.println("List of neighbors :");
					for (Integer i : sstate.neighbors.keySet()) {
						System.out.println(i + "\t[" + "]");
					}
					System.out.println("End of list");
				}
				else if (s.equals("status")) {
					if (sstate.active) { System.out.println("Active"); }
					else { System.out.println("NOT active"); }
				}
				else {
					System.out.println("Unknown command, list of known command :");
					System.out.println("- election: start process of election");
					System.out.println("- askmutex: ask for a new mutex");
					System.out.println("- tokenmutex: create the first token mutex");
					System.out.println("- hasmutex: tellf if this server has the mutex token");
					System.out.println("- identity: list of neighbors identities");
					System.out.println("- status: tells if the server is active or not");
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
